package br.unifor.cct.mia.initialize;

import java.util.List;

import br.unifor.cct.mia.dataenhancement.Attribute;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.evolutionary.FeatureConstructionGenotype;
import br.unifor.cct.mia.ga.Ga;
import br.unifor.cct.mia.ga.util.FeatureConstructionGene;
import br.unifor.cct.mia.ga.util.FeatureConstructionOperators;
import br.unifor.cct.mia.util.Methods;

public class FeatureConstructionInitialize implements Initialize {

	public Object execute(Object value) {	
		Object[] o = (Object[]) value;
		Structure struc = (Structure) o[0];
		Ga Ga = (Ga)o[1];
				
		Ga.population = new FeatureConstructionGenotype[Ga.configurations.getPopsize()+1];
        
        for (int i = 0; i < Ga.configurations.getPopsize(); i++) {
        	Ga.population[i] = new FeatureConstructionGenotype(Ga.configurations);
        	
        	Ga.population[i].setFitness(0);
        	Ga.population[i].setSelectProbability(0);                 
            
        	FeatureConstructionGene genes[] = new FeatureConstructionGene[Ga.configurations.getNvars()];
            for (int j = 0; j < Ga.configurations.getNvars(); j++) { 
            	int dbSize = struc.size();
            	
            	int attNum = Methods.randIntValue(0,dbSize-1);
            	Attribute atributo = struc.getAttribute(attNum);
            	List values = struc.getValues(attNum);
            	int vlNum = Methods.randIntValue(0,values.size()-1);
            	
            	FeatureConstructionGene gene = new FeatureConstructionGene();
            	gene.setAttribute( atributo.getName() );
            	gene.setAttPosition(attNum);
            	
            	if ( atributo.getTipo().equals(Attribute.CONTINUOUS) ) {
            		if ( atributo.isInteger() ) {
            			int vl = Methods.randIntValue( (int)atributo.getMin(),(int)atributo.getMax() );
            			gene.setValue( String.valueOf( vl ) );	
            		}
            		else {
            			double vl = Methods.randDoubleValue( atributo.getMin(),atributo.getMax() );
            			gene.setValue( String.valueOf( vl ) );
            		}
            	}
            	else {
            		gene.setValue( String.valueOf( values.toArray()[vlNum] ) );	
            	}
            	
            	gene.setActiveBit((byte)Methods.randIntValue(0,1));
            	
            	if ( atributo.getTipo().equalsIgnoreCase(Attribute.DISCRETE) ) {
            		gene.setOperator( FeatureConstructionOperators.IGUAL );
            	}
            	else {
            		gene.setOperator( FeatureConstructionOperators.getRandom() );
            	}
            	genes[j] = gene;
            }
            Methods.verificarMinActive(genes);
            ((FeatureConstructionGenotype)Ga.population[i]).setGene(genes);            
        }
	        
		return Ga.population;
	}

}
